package com.sc.token;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * token生成和验证模板
 */
@Component
public class TokenTemplate {
    @Autowired //注入配置类，读取设置的密钥过期时间
    TokenProperties tokenProperties;

    /**
     * 创建token
     * @param payload 前端请求中携带信息
     * @return  token字符
     */
    public String generateToken(Map<String,?> payload){

        return JWT.create().withHeader(getHeader())  //根据固定的信息，设置token的头部
                .withExpiresAt(getExpireTime())      //设置token过期时间
                .withPayload(payload)                //根据请求中加载信息，生成token的负载部分（第二段）
                .sign(Algorithm.HMAC256(tokenProperties.getPrivateKey()));
                //sign标签，选择加密方式和自定义密钥 用于生成token的签名部分
                /*Algorithm：算法*/
    }

    /**
     * 验证token是否正确
     * @param token token字符串（只有使用同一个密钥产生的token才能验证成功？）
     * @return token验证结果
     */
    public TokenValidationResult validationToken(String token){
        /*Verifier：验证，require：要求*/
        JWTVerifier jwtVerifier =  JWT.require(Algorithm.HMAC256(tokenProperties.getPrivateKey())).build();
        /*解码*/
        DecodedJWT decodedJWT = null;
        try {
            decodedJWT = jwtVerifier.verify(token); //验证
        }catch (JWTDecodeException e){
            return new TokenValidationResult(0,"token无效",null);
        }catch(TokenExpiredException e){
            return new TokenValidationResult(0,"token已过期",null);
        }
        return new TokenValidationResult(1,"token验证成功",decodedJWT.getClaims());
    }

    /**
     * 获取token的头部
     * @return token的加密密钥信息？
     */
    Map<String,Object> getHeader(){
        Map<String,Object> map = new HashMap<>();
        map.put("typ","jwt");
        map.put("alg","HMAC256");
        return map;
    }

    /**
     * 根据当前时间和配置的token过期时长，计算token的过期时间
     * @return 过期时间
     */
    Date getExpireTime(){
        return new Date(System.currentTimeMillis() + tokenProperties.getExpireTime());
    }
}
